﻿using Prism.DryIoc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Interop;

namespace PlaceOrder_Client.Helper
{

    public class GlobalHotKey
    {
        private const int WM_HOTKEY = 0x0312;
        private IntPtr hWnd;
        private Action callback;
        private int currentId;

        public GlobalHotKey(Key key, ModifierKeys modifierKeys, Action action)
        {
            callback = action;
            hWnd = new WindowInteropHelper(PrismApplication.Current.MainWindow).Handle;
            RegisterHotKey(hWnd, key, modifierKeys);
            ComponentDispatcher.ThreadPreprocessMessage += ProcessMessage;
        }

        private void ProcessMessage(ref System.Windows.Interop.MSG msg, ref bool handled)
        {
            if (msg.message == WM_HOTKEY && (int)(msg.wParam.ToInt64()) == currentId)
            {
                callback?.Invoke();
                handled = true;
            }
        }

        ~GlobalHotKey()
        {
            ComponentDispatcher.ThreadPreprocessMessage -= ProcessMessage;
            for (int i = 0; i < 0x100; i++)
            {
                UnregisterHotKey(hWnd, i);
            }
        }

    

        private void RegisterHotKey(IntPtr hWnd, Key key, ModifierKeys modifierKeys)
        {
            currentId = key.GetHashCode() ^ (int)modifierKeys << 16;
            RegisterHotKey(hWnd, currentId, (uint)modifierKeys, (uint)KeyInterop.VirtualKeyFromKey(key));
        }

        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        [StructLayout(LayoutKind.Sequential)]
        private struct MSG
        {
            public IntPtr hwnd;
            public uint message;
            public IntPtr wParam;
            public IntPtr lParam;
            public uint time;
            public System.Drawing.Point p;
        }
    }

}
